<!DOCTYPE html>
<head>
	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
	<title>Calculate Progress of Summary Tasks</title>
	<script src="../../codebase/dhtmlxgantt.js?v=7.1.0"></script>
	<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.0">

	<script src="../common/testdata.js?v=7.1.0"></script>
	<style>
		html, body {
			height: 100%;
			padding: 0px;
			margin: 0px;
			overflow: hidden;
		}

		.gantt_task_line.gantt_dependent_task {
			background-color: #65c16f;
			border: 1px solid #3c9445;
		}

		.gantt_task_line.gantt_dependent_task .gantt_task_progress {
			background-color: #46ad51;
		}

		.hide_project_progress_drag .gantt_task_progress_drag {
			visibility: hidden;
		}

		.gantt_task_progress {
			text-align: left;
			padding-left: 10px;
			box-sizing: border-box;
			color: white;
			font-weight: bold;
		}
	</style>
</head>

<body>
<div id="gantt_here" style='width:100%; height:100%;'></div>
<script>


	// recalculate progress of summary tasks when the progress of subtasks changes
	(function dynamicProgress() {

		function calculateSummaryProgress(task) {
			if (task.type != gantt.config.types.project)
				return task.progress;
			var totalToDo = 0;
			var totalDone = 0;
			gantt.eachTask(function (child) {
				if (child.type != gantt.config.types.project) {
					totalToDo += child.duration;
					totalDone += (child.progress || 0) * child.duration;
				}
			}, task.id);
			if (!totalToDo) return 0;
			else return totalDone / totalToDo;
		}

		function refreshSummaryProgress(id, submit) {
			if (!gantt.isTaskExists(id))
				return;

			var task = gantt.getTask(id);
			task.progress = calculateSummaryProgress(task);

			if (!submit) {
				gantt.refreshTask(id);
			} else {
				gantt.updateTask(id);
			}

			if (!submit && gantt.getParent(id) !== gantt.config.root_id) {
				refreshSummaryProgress(gantt.getParent(id), submit);
			}
		}


		gantt.attachEvent("onParse", function () {
			gantt.eachTask(function (task) {
				task.progress = calculateSummaryProgress(task);
			});
		});

		gantt.attachEvent("onAfterTaskUpdate", function (id) {
			refreshSummaryProgress(gantt.getParent(id), true);
		});

		gantt.attachEvent("onTaskDrag", function (id) {
			refreshSummaryProgress(gantt.getParent(id), false);
		});
		gantt.attachEvent("onAfterTaskAdd", function (id) {
			refreshSummaryProgress(gantt.getParent(id), true);
		});


		(function () {
			var idParentBeforeDeleteTask = 0;
			gantt.attachEvent("onBeforeTaskDelete", function (id) {
				idParentBeforeDeleteTask = gantt.getParent(id);
			});
			gantt.attachEvent("onAfterTaskDelete", function () {
				refreshSummaryProgress(idParentBeforeDeleteTask, true);
			});
		})();
	})();


	var demo_tasks = {
		data: [
			{id: 11, text: "Project #1", start_date: "", duration: "", progress: 0.6, open: true, type: gantt.config.types.project},
			{id: 12, text: "Task #1", start_date: "03-04-2018", duration: "5", parent: "11", progress: 1, open: true, type: gantt.config.types.task},
			{id: 13, text: "Task #2", start_date: "", duration: "", parent: "11", progress: 0.4, open: true, type: gantt.config.types.project},
			{id: 14, text: "Task #3", start_date: "02-04-2018", duration: "6", parent: "11", progress: 0.8, open: true, type: gantt.config.types.task},
			{id: 15, text: "Task #4", start_date: "", duration: "", parent: "11", progress: 0.18, open: true, type: gantt.config.types.project},
			{id: 16, text: "Task #5", start_date: "02-04-2018", duration: "7", parent: "11", progress: 0, open: true, type: gantt.config.types.task},
			{id: 17, text: "Task #2.1", start_date: "03-04-2018", duration: "2", parent: "13", progress: 1, open: true, type: gantt.config.types.task},
			{id: 18, text: "Task #2.2", start_date: "06-04-2018", duration: "3", parent: "13", progress: 0.8, open: true, type: gantt.config.types.task},
			{id: 19, text: "Task #2.3", start_date: "10-04-2018", duration: "4", parent: "13", progress: 0.2, open: true, type: gantt.config.types.task},
			{id: 20, text: "Task #2.4", start_date: "10-04-2018", duration: "4", parent: "13", progress: 0, open: true, type: gantt.config.types.task},
			{id: 21, text: "Task #4.1", start_date: "03-04-2018", duration: "4", parent: "15", progress: 0.5, open: true, type: gantt.config.types.task},
			{id: 22, text: "Task #4.2", start_date: "03-04-2018", duration: "4", parent: "15", progress: 0.1, open: true, type: gantt.config.types.task},
			{id: 23, text: "Task #4.3", start_date: "03-04-2018", duration: "5", parent: "15", progress: 0, open: true, type: gantt.config.types.task}
		],
		links: [
			{id: "10", source: "11", target: "12", type: "1"},
			{id: "11", source: "11", target: "13", type: "1"},
			{id: "12", source: "11", target: "14", type: "1"},
			{id: "13", source: "11", target: "15", type: "1"},
			{id: "14", source: "11", target: "16", type: "1"},
			{id: "15", source: "13", target: "17", type: "1"},
			{id: "16", source: "17", target: "18", type: "0"},
			{id: "17", source: "18", target: "19", type: "0"},
			{id: "18", source: "19", target: "20", type: "0"},
			{id: "19", source: "15", target: "21", type: "2"},
			{id: "20", source: "15", target: "22", type: "2"},
			{id: "21", source: "15", target: "23", type: "2"}
		]
	};

	gantt.config.lightbox.sections = [
		{name: "description", height: 70, map_to: "text", type: "textarea", focus: true},
		{name: "time", type: "duration", map_to: "auto"}
	];


	gantt.config.scale_height = 50;
	gantt.config.auto_types = true;

	gantt.config.scales = [
		{unit: "month", step: 1, format: "%F, %Y"},
		{unit: "day", step: 1, format: "%j, %D"}
	];

	gantt.templates.progress_text = function (start, end, task) {
		return "<span style='text-align:left;'>" + Math.round(task.progress * 100) + "% </span>";
	};

	gantt.templates.task_class = function (start, end, task) {
		if (task.type == gantt.config.types.project)
			return "hide_project_progress_drag";
	};


	gantt.init("gantt_here");
	gantt.parse(demo_tasks);


</script>
</body>